package com.wili.insertLog;
import java.io.File;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import com.c.Ca;
import com.wili.c.Class9;
import com.wili.c.File9;
import _a.Logu;
/**
 * 	Cache for funName, funLineNo etc, 
 * 	Which first get from instance of StackTraceElement.
 * @author weila 2021-2-3
 */
public class InfunMap {
	/**
	 *  logId ~> {fun.lineNo, fun.name, fun.className, ...}
	 */
	private static Map<Integer, Infun> LogIdToFunInfoMap = new HashMap<>();

	static final File file = new File(Logu.ConfRoot, InfunMap.class.getName());
	static {
		LogIdToFunInfoMap = File9.readObject(file, null, "");
		if (LogIdToFunInfoMap == null)
			LogIdToFunInfoMap = new HashMap<>();
	}
	public static class Infun implements Serializable {
		private static final long serialVersionUID = 1L;

		public final String clsName, sName, funName, sfName;

		public final int lineNo;

		public final String linkStr;
		public String toString() {
			return sfName;
		}

		public Infun(StackTraceElement ele) {
			String nam = ele.getClassName();
			if (nam.contains("$")) {
				Class<?> cls = Class9.forName(nam, -1);
				cls = Class9.fileClassOf(cls);
				if (cls != null) {
					nam = cls.getName();
				}
			}
			this.clsName = nam;
			//频繁打印超连接到控制台是很耗费的, 限制控制台buffer size即可。
			this.sName = clsName.substring(clsName.lastIndexOf('.') + 1);
			this.lineNo = ele.getLineNumber();
			String fname = ele.getMethodName();
			if (Boolean.FALSE && fname.equals("<init>")) {
				funName = sName;
			} else {
				funName = fname;
			}
			this.sfName = sName + "." + funName;
			this.linkStr = "at " + ele.getMethodName() + " (" + sName + ".java:" + lineNo + ")";
		}
	}
	/**
	 * 	据此缓存可节省重复的 getStackTrace 耗费。
	 */
	public static Infun getInfun(int logId) {
		Infun ret = LogIdToFunInfoMap.get(logId);
		//ret = null;
		if (ret == null) {
			StackTraceElement[] ee = new Throwable().getStackTrace();
			LogIdToFunInfoMap.put(logId, ret = new Infun(ee[stackTraceInd]));//2
		}
		return ret;
	}
	static final int stackTraceInd = 2;//2;
	public static void saveToFile() {
		File9.writeObject(LogIdToFunInfoMap, file, -1);
	}

	public static void removeFile() {
		if (file.exists() && !file.delete()) {
			Ca.debug(1, "删除文件失败：" + file.getAbsolutePath());
		}
	}
}
